package org.example.spring.self.demo;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Configurable;
import org.springframework.beans.factory.config.BeanFactoryPostProcessor;
import org.springframework.beans.factory.config.BeanPostProcessor;
import org.springframework.beans.factory.support.AbstractBeanDefinition;
import org.springframework.beans.factory.support.BeanDefinitionBuilder;
import org.springframework.beans.factory.support.DefaultListableBeanFactory;
import org.springframework.context.annotation.AnnotationConfigUtils;
import org.springframework.context.annotation.Bean;

import javax.annotation.Resource;
import java.util.Map;

/**
 * 文件描述
 *
 * @author yezhou41127
 * @date: 2022年07月29日
 */
public class TestBeanFactory {

	public static void main(String[] args) {
		DefaultListableBeanFactory beanFactory = new DefaultListableBeanFactory();

		// bean 的定义 class scope 初始化 销毁 bean 的描述信息
		AbstractBeanDefinition configBeanDefinition = BeanDefinitionBuilder
				.genericBeanDefinition(Config.class)
				.setScope("singleton").getBeanDefinition();

		beanFactory.registerBeanDefinition("config", configBeanDefinition);
		// beanFactory 未解析注解 @Configurable @Bean...

		// 给 beanFactory 添加 常用的 后处理器
		AnnotationConfigUtils.registerAnnotationConfigProcessors(beanFactory);

		// 获取所有 beanFactory 后处理器
		Map<String, BeanFactoryPostProcessor> beanFactoryPostProcessorBeans = beanFactory.getBeansOfType(BeanFactoryPostProcessor.class);

		// 逐个执行 beanFactory 后处理器 解析 @Bean 并没有进行 依赖注入
		beanFactoryPostProcessorBeans.values().forEach(postProcessor -> {
			postProcessor.postProcessBeanFactory(beanFactory);
		});

		for (String beanDefinitionName : beanFactory.getBeanDefinitionNames()) {
			System.out.println(beanDefinitionName);
		}

/*		Bean1 bean1 = beanFactory.getBean(Bean1.class);
		// 会调用 bean1 的构造方法
		// bean1.bean2 null
		System.out.println(bean1.getBean2());*/

		// 获取所有 bean 的后处理器 bean生命周期的各个阶段，提供扩展 例如 依赖注入 @Autowired @Resource
		Map<String, BeanPostProcessor> beanPostProcessorBeans = beanFactory.getBeansOfType(BeanPostProcessor.class);

		// 建立 beanFactory 与后处理器的联系
		// 使用比较器 修改 beanPostProcessor 顺序
		beanPostProcessorBeans.values().stream().sorted(beanFactory.getDependencyComparator()).forEach(postProcessor -> {
			System.out.println(">>>" + postProcessor);
			beanFactory.addBeanPostProcessor(postProcessor);
		});
		// 预先实例化单例对象
		beanFactory.preInstantiateSingletons();
		System.out.println("------");

		Bean1 bean1 = beanFactory.getBean(Bean1.class);
		// 会调用 bean1 的构造方法
		// bean1.bean2 null
		System.out.println(bean1.bean3);
	}

	@Configurable
	static class Config {
		@Bean
		public Bean1 bean1() {
			return new Bean1();
		}

		@Bean
		public Bean2 bean2() {
			return new Bean2();
		}

		@Bean
		public Bean3 bean3() {
			return new Bean3();
		}

		@Bean
		public Bean4 bean4() {
			return new Bean4();
		}
	}

	static class Bean1 {

		public Bean1() {
			System.out.println("构造 Bean1()");
		}

		@Autowired
		private Bean2 bean2;

		public Bean2 getBean2() {
			return bean2;
		}

		@Autowired
		@Resource(name = "bean4")
		private Inter bean3;
	}

	static class Bean2 {

		public Bean2() {
			System.out.println("构造 Bean2()");
		}

		@Autowired
		private Bean1 bean1;

		public Bean1 getBean1() {
			return bean1;
		}
	}

	interface Inter {
	}

	static class Bean3 implements Inter {
	}

	static class Bean4 implements Inter {
	}
}
